#include <asteroid/Game.hpp>

#include <iostream>

#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>

#include <iostream>

Game::Game(sf::RenderWindow* window) : window(window), player(sf::Vector2f{60, 80})
{
	this->player.setFillColor(sf::Color::Magenta);
}

void Game::run()
{
	while(!this->quit)
	{
		this->update();
		this->draw();
	}
}

void Game::processEvents()
{
	sf::Event event;
	while (window->pollEvent(event))
	{
		if(event.type == sf::Event::Closed)
		{
			this->quit = true;
		}
		else if(event.type == sf::Event::KeyPressed)
		{
			if(event.key.code == sf::Keyboard::Space)
			{
				this->shoots.push_back(this->player.getShoot());
			}
		}
	}

	//Player movement
	if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
	{
		this->player.move(sf::Vector2f(-5, 0));
	}
	if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
	{
		this->player.move(sf::Vector2f(5, 0));
	}
	if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
	{
		this->player.move(sf::Vector2f(0, -5));
	}
	if(sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
	{
		this->player.move(sf::Vector2f(0, 5));
	}
}

void Game::checkCollisions() //Unoptimized as much as possible
{
	//Player window collisions
	//Warning hardcoded values...
	//Bug with passing trought borders in corners when diagonal movement
	//4 ifs don't fix the bug

	sf::FloatRect playerRect = this->player.getGlobalBounds();

	if(playerRect.top < 0)
	{
		this->player.setPosition({playerRect.left, 0});
	}
	else if(playerRect.top + playerRect.height > 720)
	{
		this->player.setPosition({playerRect.left, 720 - playerRect.height});
	}
	else if(playerRect.left < 0)
	{
		this->player.setPosition({0, playerRect.top});
	}
	else if(playerRect.left + playerRect.width > 1280)
	{
		this->player.setPosition({1280 - playerRect.width, playerRect.top});
	}

	//bullets collision with screen
	for(std::list<sf::RectangleShape*>::iterator it = this->shoots.begin(); it != this->shoots.end(); ++it)
	{
		sf::FloatRect shootRectangle = (*it)->getGlobalBounds();
		if(shootRectangle.top + shootRectangle.height < 0)
		{
			it = this->shoots.erase(it);
		}
	}
}

void Game::draw()
{
	window->clear(sf::Color::Black);
	{
		window->draw(this->player);
		this->drawRectangleShapes(this->shoots);
		this->drawRectangleShapes(this->asteroids);
	}
	window->display();
}

void Game::drawRectangleShapes(std::list<sf::RectangleShape*> shapes)
{
	for(const auto shape : shapes)
	{
		window->draw(*shape);
	}
}

void Game::update()
{
	this->processEvents();
	this->moveAsteroids();
	this->moveShoots();
	this->checkCollisions();
}

void Game::moveShoots()
{
	for(auto shoot : this->shoots)
	{
		shoot->move({0, -7});
	}
}

void Game::moveAsteroids()
{
	for(auto asteroid : this->asteroids)
	{
		asteroid->move({0, 3});
	}
}
